package cn.stylefeng.guns.modular.business.custom.excel;

import cn.hutool.core.date.DateUtil;
import cn.stylefeng.guns.modular.business.custom.excel.controller.BaseFrontController;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author liwenlong
 * @date 2023/3/9 19:00
 */
@Component
@Slf4j
public class ExcelUtil {



    public static void main(String[] args) {

        List<ExcelParam> excelParams = new ArrayList<>();

        excelParams.add(new ExcelParam("id","id",5000));

        excelParams.add(new ExcelParam("订单号","orderNo",5000));

        excelParams.add(new ExcelParam("支付时间","payTime",5000));

//        List list  = new ArrayList();
//        exportExcel(list,excelParams);
    }



    /**
     * 导出
     * @param list
     * @param excelParams
     * @return
     */
    public  ResponseEntity<byte[]> exportExcel(List list,List<ExcelParam> excelParams){

        try {
            log.info(">>>>>>>>>>开始导出excel>>>>>>>>>>");
            //求出导出数据
            BaseFrontController baseFrontController = new BaseFrontController();
            return baseFrontController.buildResponseEntity(export(list,excelParams), "导出数据.xls");
        } catch (Exception e) {
            e.printStackTrace();
            log.error(">>>>>>>>>>导出excel 异常，原因为：" + e.getMessage());
        }

        return null;
    }



    private InputStream export(List<T> list,List<ExcelParam> excelParams) {

        log.info(">>>>>>>>>>>>>>>>>>>>开始进入导出方法>>>>>>>>>>");
        ByteArrayOutputStream output = null;
        InputStream inputStream1 = null;
        SXSSFWorkbook wb = new SXSSFWorkbook(1000);// 保留1000条数据在内存中
        SXSSFSheet sheet = wb.createSheet();
        // 设置报表头样式
        CellStyle header = ExcelFormatUtil.headSytle(wb);// cell样式
        CellStyle content = ExcelFormatUtil.contentStyle(wb);// 报表体样式


        //标头
        List keys= new ArrayList();

        // 每一列字段名
        List<String> values = new ArrayList();

        // 列宽
        List<Integer> ints = new ArrayList();

        excelParams.stream().forEach(s->{
            keys.add(s.getName());
            values.add(s.getField());
            ints.add(s.getWidth());
        });

        // 设置表头样式
        ExcelFormatUtil.initTitleEX(sheet, header, keys, ints);
        log.info(">>>>>>>>>>>>>>>>>>>>表头样式设置完成>>>>>>>>>>");
        int x = 0;
        if (list != null && list.size() > 0) {
            log.info(">>>>>>>>>>>>>>>>>>>>开始遍历数据组装单元格内容>>>>>>>>>>");
            for (int i = 0; i < list.size(); i++) {

                Object t = list.get(i);

                SXSSFRow row = sheet.createRow(i + 1);
                x++;

                //根据对象反射
                Class<?> clazz= t.getClass();

                //根据反射机制获取对象的所有字段，包含public、private和proteced
                Field[] declaredFields=clazz.getDeclaredFields();

                int j = 0;
                //循环判断对象中的字段
                for (int n = 0; n < declaredFields.length; n++) {

                    Field field = declaredFields[n];
                    //设置属性可访问
                    declaredFields[n].setAccessible(true);
                    try {

                        if (values.size() <= j){
                            break;
                        }

                        //获取字段名称
                        String s = values.get(j);

                        if (!s.equals(field.getName())){
                            continue;
                        }

                        Object value = field.get(t);
                        SXSSFCell cell = row.createCell(j++);

                        //excel赋值 根据不同类型判断
                        if (field.getType().equals(Date.class)) {
                            String format = DateUtil.format((Date) value, "yyyy-MM-dd HH:mm:ss");
                            cell.setCellValue(format);
                        } else {
                            cell.setCellValue(value.toString());
                        }

                        //报表体样式
                        cell.setCellStyle(content);

                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
            log.info(">>>>>>>>>>>>>>>>>>>>结束遍历数据组装单元格内容>>>>>>>>>>");
        }

        try {
            output = new ByteArrayOutputStream();
            wb.write(output);
            inputStream1 = new ByteArrayInputStream(output.toByteArray());
            output.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (output != null) {
                    output.close();
                    if (inputStream1 != null)
                        inputStream1.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return inputStream1;
    }

}
